package org.uim.cricket.analyzer.parsers.match.impl;

import java.util.Arrays;
import java.util.Calendar;

import org.uim.cricket.analyzer.parsers.Plogger;
import org.uim.cricket.analyzer.parsers.match.MatchDatesParsable;
import org.uim.cricket.analyzer.parsers.match.MatchSpanParsable;
import org.uim.cricket.entities.match.CricketMatch;
import org.uim.cricket.entities.match.MatchDates;
import org.uim.cricket.util.HTMLStringUtils;
import org.uim.cricket.util.MyStringUtils;

public class DefaultMatchDatesParser implements MatchDatesParsable {
	
	private MatchSpanParsable spanParser = null;
	
	private boolean sortDates = true;
	
	public DefaultMatchDatesParser() {
	    
	}
	
	public DefaultMatchDatesParser(MatchSpanParsable theSpanParser) {
	    this.spanParser = theSpanParser;
	}
	
	@Override
	public MatchDates parseMatchDates(String source, CricketMatch match) {
		if (source == null) return null;
		source = HTMLStringUtils.cleanHTMLTags(source, true);
		
		int dashpos = source.indexOf('-');
		int parapos = source.indexOf('(');
		MatchDates dates = null;
		
		if (parapos < dashpos) {
			dates = getDates(source.substring(0, parapos).trim());
		} else if (parapos > dashpos) {
			dates = getDates(source.substring(0, dashpos).trim());
			source = source.substring(dashpos + 1);
			if (source.indexOf("day/night") >= 0) {
				match.setDayNight(true);
			}
		}
		
		parapos = source.indexOf('(');
        if (spanParser != null) {
            Plogger.debug("    started span parsing...");
            match.setSpans(spanParser.getSpanData(source.substring(parapos + 1)));
            Plogger.debug("    completed span parsing.");
        }
		
		return dates;
	}
	
	private MatchDates getDates(String source) {	
		MatchDates dates = new MatchDates();
		String[] parts = source.split("[,]");
		
		int year = 0;
        int month = 0;
        int day = 0;
        Calendar[] calendars = new Calendar[parts.length];
        
        for (int i = parts.length - 1; i >= 0; i--) {
            parts[i] = parts[i].trim();
            
            String[] subs = parts[i].split("[ ]+");
            if (subs.length < 1) continue;
            if (subs.length > 3) continue;

            if (subs.length == 2) {
            	if (!MyStringUtils.isNumeric(subs[0]) && MyStringUtils.isNumeric(subs[1])) {
            		month = getMonth( subs[0] );
            		year = Integer.parseInt(subs[1]);
            		continue;
            	}
            }
            day = Integer.parseInt(subs[0]);

            if (subs.length >= 2) {
                month = getMonth( subs[1] );
                if (month >= 12 || month < 0) {
                    Plogger.warn("    unidentified month name: " + subs[1]);
                }
                
                if (subs.length == 3) {
                    year = Integer.parseInt(subs[2]);
                } 
            }

            Calendar cal = Calendar.getInstance();
            cal.set(year, month, day);
            calendars[i] = cal;    
        }
		
        Arrays.sort(calendars);
        
        dates.setDates(calendars);
		return dates;
	}
	
	private int getMonth(String month) {
		String prefix = month.toLowerCase().substring(0, 3);
		if (prefix.equals("jan")) return Calendar.JANUARY;
		else if (prefix.equals("feb")) return Calendar.FEBRUARY;
		else if (prefix.equals("mar")) return Calendar.MARCH;
		else if (prefix.equals("apr")) return Calendar.APRIL;
		else if (prefix.equals("may")) return Calendar.MAY;
		else if (prefix.equals("jun")) return Calendar.JUNE;
		else if (prefix.equals("jul")) return Calendar.JULY;
		else if (prefix.equals("aug")) return Calendar.AUGUST;
		else if (prefix.equals("sep")) return Calendar.SEPTEMBER;
		else if (prefix.equals("oct")) return Calendar.OCTOBER;
		else if (prefix.equals("nov")) return Calendar.NOVEMBER;
		else if (prefix.equals("dec")) return Calendar.DECEMBER;
		else
			return -1;
    }
	
	public boolean isSortDates() {
		return sortDates;
	}
	
	public void setSortDates(boolean sortDates) {
		this.sortDates = sortDates;
	}
}
